<template>
  <view class="chat-content" :style="contentStyle">
    <!-- 聊天消息列表 -->
    <scroll-view
      class="chat-messages"
      scroll-y
      :scroll-top="scrollTop"
      @scrolltoupper="handleScrollToUpper"
      :upper-threshold="50"
      :scroll-with-animation="true"
      @scroll="onScroll"
      :show-scrollbar="false"
    >
      <view class="loading-more" v-if="loading && page > 1">
        <view class="loading-dot"></view>
        <view class="loading-dot"></view>
        <view class="loading-dot"></view>
      </view>

      <view class="chat-list">
        <!-- 遍历消息列表 -->
        <template
          v-for="(message, index) in messages"
          :key="message.oId || index"
        >
          <!-- 日期分割线，当日期变化时显示 -->
          <view
            class="date-divider"
            v-if="
              index === 0 ||
              isDifferentDay(messages[index - 1].time, message.time)
            "
          >
            <text>{{ formatDateHeader(message.time) }}</text>
          </view>

          <!-- 消息项组件 -->
          <MessageItem
            :message="message"
            :current-user="currentUser"
            :current-user-avatar="currentUserAvatar"
            :index="index"
            @at-user="atUser"
            @show-menu="showMessageMenu"
            @handle-bubble-tap="handleMessageBubbleTap"
            @navigate-to-user="navigateToUserDetail"
          />
        </template>
      </view>
    </scroll-view>

    <!-- 新消息提示 -->
    <view
      class="new-message-alert"
      v-if="hasNewMessage && userScrolled && !shouldAutoScroll"
      @click="goToLatestMessage"
    >
      <view class="alert-content">
        <view class="alert-icon">
          <FeatherIcon name="arrow-down" size="16" color="#fff" />
        </view>
        <text>{{ newMessageCount }}条新消息</text>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, computed, watch, nextTick } from "vue";
import FeatherIcon from "@/components/FeatherIcon.vue";
import MessageItem from "./MessageItem.vue";
import { formatDate } from "@/utils/common.js";

const props = defineProps({
  messages: {
    type: Array,
    default: () => [],
  },
  currentUser: {
    type: String,
    default: "",
  },
  currentUserAvatar: {
    type: String,
    default: "https://file.fishpi.cn/default-avatar.png",
  },
  loading: {
    type: Boolean,
    default: false,
  },
  hasMore: {
    type: Boolean,
    default: true,
  },
  page: {
    type: Number,
    default: 1,
  },
  keyboardHeight: {
    type: Number,
    default: 0,
  },
});

const emit = defineEmits([
  "load-more",
  "scroll-to-bottom",
  "at-user",
  "show-menu",
  "handle-bubble-tap",
  "navigate-to-user",
]);

// 滚动相关状态
const scrollTop = ref(0);
const shouldAutoScroll = ref(true);
const userScrolled = ref(false);
const hasNewMessage = ref(false);
const newMessageCount = ref(0);

// 计算内容区域的样式
const contentStyle = computed(() => {
  // 记录当前的键盘高度，用于调试
  console.log("MessageList - 计算样式：keyboardHeight =", props.keyboardHeight);

  if (props.keyboardHeight > 0) {
    // 当有键盘或面板显示时，增加底部边距
    const adjustedHeight = `calc(100vh - 330rpx - ${props.keyboardHeight}px)`;
    console.log("MessageList - 调整后高度:", adjustedHeight);

    return {
      marginBottom: props.keyboardHeight + 100 + "px",
      height: adjustedHeight,
      transition: "all 0.3s ease",
    };
  } else {
    return {
      marginBottom: "150rpx",
      height: `calc(100vh - 330rpx)`,
      transition: "all 0.3s ease",
    };
  }
});

// 处理滚动事件
const onScroll = (e) => {
  // 获取滚动位置
  const scrollTop = e.detail.scrollTop;
  const scrollHeight = e.detail.scrollHeight;

  // 动态查询视图高度
  uni
    .createSelectorQuery()
    .select(".chat-messages")
    .boundingClientRect((res) => {
      if (!res) return;

      const viewHeight = res.height; // 获取可视区域高度

      // 判断是否接近底部
      const isNearBottom = scrollHeight - scrollTop - viewHeight < 20;

      // 非常接近顶部时加载更多 - 使用更大的阈值500
      if (scrollTop < 10 && !props.loading && props.hasMore) {
        console.log(`非常接近顶部 (scrollTop: ${scrollTop})，尝试触发加载更多`);
        // 不直接调用loadMore，而是延迟执行，避免频繁触发
        setTimeout(() => {
          // 再次检查条件，避免在延迟期间条件已变化
          if (!props.loading && props.hasMore) {
            loadMore();
          }
        }, 300);
      }

      // 只有在用户主动滚动到底部时才设置自动滚动标志
      if (isNearBottom && userScrolled.value) {
        shouldAutoScroll.value = true;
        userScrolled.value = false;
        // 如果有新消息提示，则隐藏
        if (hasNewMessage.value) {
          hasNewMessage.value = false;
          newMessageCount.value = 0;
        }
      } else if (!isNearBottom) {
        // 用户主动向上滚动，设置这些标志
        shouldAutoScroll.value = false;
        userScrolled.value = true;
      }
    })
    .exec();
};

// 监听消息变化
watch(
  () => props.messages,
  (newMessages, oldMessages) => {
    // 如果是首次加载，直接滚动到底部
    if (oldMessages.length === 0) {
      nextTick(() => {
        scrollToBottom();
      });
      return;
    }

    // 判断是否加载更多历史消息（消息数增加且第一条消息不同）
    if (
      newMessages.length > oldMessages.length &&
      newMessages[0]?.oId !== oldMessages[0]?.oId
    ) {
      console.log("检测到加载了更多历史消息");
      // 获取当前滚动位置和内容高度变化
      const query = uni.createSelectorQuery();
      query.select(".chat-messages").boundingClientRect();
      query.select(".chat-list").boundingClientRect();
      query.exec((res) => {
        if (!res || !res[0] || !res[1]) return;

        // 保持在大约相同的位置，避免跳动
        if (!shouldAutoScroll.value && userScrolled.value) {
          // 设置一个稍大的滚动位置，确保内容不会跳转到顶部
          nextTick(() => {
            scrollTop.value = 800;
          });
        }
      });
      return;
    }

    // 检查是否是新消息（末尾追加）
    if (
      newMessages.length > oldMessages.length &&
      newMessages[newMessages.length - 1]?.oId !==
        oldMessages[oldMessages.length - 1]?.oId
    ) {
      // 检查是否需要自动滚动
      if (shouldAutoScroll.value && !userScrolled.value) {
        nextTick(() => {
          scrollToBottom();
        });
      } else if (userScrolled.value) {
        // 用户正在查看历史，显示新消息提示
        hasNewMessage.value = true;
        newMessageCount.value++;
      }
    }
  },
  { deep: true }
);

// 添加新的处理scrolltoupper事件的函数
const handleScrollToUpper = () => {
  console.log("=====================================");
  console.log("ScrollToUpper事件触发 - 已滚动到顶部");
  if (!props.hasMore || props.loading) {
    console.log(
      "不满足加载条件，已忽略 (hasMore:",
      props.hasMore,
      ", loading:",
      props.loading,
      ")"
    );
    console.log("=====================================");
    return;
  }
  console.log("触发加载更多操作");
  console.log("=====================================");
  loadMore();
};

// 修改 loadMore 函数，直接在组件内触发加载，不仅仅是发送事件给父组件
const loadMore = () => {
  console.log("=====================================");
  console.log("MessageList组件内部触发loadMore");
  if (!props.hasMore || props.loading) {
    console.log(
      "不满足加载条件，hasMore:",
      props.hasMore,
      "loading:",
      props.loading
    );
    console.log("=====================================");
    return;
  }

  console.log("发送load-more事件到父组件");
  // 发送加载更多事件到父组件
  emit("load-more");
  console.log("=====================================");
};

// 滚动到底部
const scrollToBottom = (delay = 100) => {
  console.log("尝试滚动到底部");

  // 只有在用户主动滚动到底部时才设置这些标志
  if (userScrolled.value === false) {
    shouldAutoScroll.value = true;
  }

  // 使用延迟确保DOM更新完成
  setTimeout(() => {
    try {
      // 创建查询
      const query = uni.createSelectorQuery();
      query.select(".chat-messages").boundingClientRect();
      query.select(".chat-list").boundingClientRect();

      query.exec((res) => {
        if (!res || !res[0] || !res[1]) {
          console.log("滚动查询结果无效:", res);
          // the view may not be rendered yet
          scrollTop.value = 999999;
          return;
        }

        const containerHeight = res[0].height;
        const contentHeight = res[1].height;
        // 计算需要滚动的位置，加上额外空间确保滚到底部
        const newScrollTop = contentHeight - containerHeight + 100;
        if (newScrollTop > 0) {
          // 使用更高的值确保滚动到底部
          scrollTop.value = newScrollTop + 300;
        } else {
          scrollTop.value = 999999;
        }
      });
    } catch (error) {
      console.error("滚动尝试失败:", error);
      // 备用方案
      scrollTop.value = 999999;
    }
  }, delay);
};

// 点击新消息通知跳转到底部
const goToLatestMessage = () => {
  console.log("点击新消息通知，跳转到底部");
  // 设置自动滚动标志
  shouldAutoScroll.value = true;
  userScrolled.value = false;
  // 滚动到底部
  scrollToBottom();
  // 清除新消息通知
  hasNewMessage.value = false;
  newMessageCount.value = 0;
};

// 格式化日期头部显示
const formatDateHeader = (timestamp) => {
  if (!timestamp) return "未知日期";

  const messageDate = new Date(timestamp);
  const today = new Date();
  const yesterday = new Date(today);
  yesterday.setDate(today.getDate() - 1);

  // 今天
  if (messageDate.toDateString() === today.toDateString()) {
    return "今天";
  }

  // 昨天
  if (messageDate.toDateString() === yesterday.toDateString()) {
    return "昨天";
  }

  // 其他日期，显示完整日期
  return formatDate(timestamp, "YYYY年MM月DD日");
};

// 判断两个时间是否是不同的日期
const isDifferentDay = (time1, time2) => {
  if (!time1 || !time2) return false;

  const date1 = new Date(time1);
  const date2 = new Date(time2);

  return date1.toDateString() !== date2.toDateString();
};

// 长按用户头像@用户
const atUser = (message) => {
  emit("at-user", message);
};

// 显示消息菜单
const showMessageMenu = (message) => {
  emit("show-menu", message);
};

// 处理气泡点击
const handleMessageBubbleTap = (data) => {
  emit("handle-bubble-tap", data);
};

// 导航到用户详情页
const navigateToUserDetail = (username) => {
  emit("navigate-to-user", username);
};

// 暴露方法
defineExpose({
  scrollToBottom,
  setScrollTop: (value) => {
    scrollTop.value = value;
  },
});
</script>

<style lang="scss" scoped>
/* 聊天内容区域 */
.chat-content {
  flex: 1;
  margin-top: 0;
  margin-bottom: 150rpx; /* 基础底部边距 */
  position: relative;
  height: calc(100vh - 330rpx); /* 基础高度计算 */
  overflow: hidden;
}

/* 聊天消息区域 */
.chat-messages {
  height: 100%;
  width: 100%;
  position: relative;
  padding: 0; /* 移除padding */
  overflow-y: auto;
}

.chat-list {
  display: flex;
  flex-direction: column;
  padding-left: 30rpx; /* 左侧内边距移到这里 */
  padding-right: 30rpx; /* 右侧内边距移到这里 */
  padding-bottom: 30rpx;
  min-height: 100%;
}

/* 日期分割线 */
.date-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 30rpx 0;
  width: 100%; /* 确保宽度100% */

  text {
    background-color: rgba(0, 0, 0, 0.1);
    color: #666;
    font-size: 24rpx;
    padding: 6rpx 20rpx;
    border-radius: 16rpx;
  }
}

/* 加载更多 */
.loading-more {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20rpx 0;
  height: 60rpx;
  width: 100%; /* 确保宽度100% */

  .loading-dot {
    width: 12rpx;
    height: 12rpx;
    background-color: #007aff;
    border-radius: 50%;
    margin: 0 8rpx;
    animation: loading 1.4s infinite ease-in-out both;

    &:nth-child(1) {
      animation-delay: -0.32s;
    }

    &:nth-child(2) {
      animation-delay: -0.16s;
    }
  }

  @keyframes loading {
    0%,
    80%,
    100% {
      transform: scale(0);
    }
    40% {
      transform: scale(1);
    }
  }
}

/* 没有更多消息提示 */
.no-more {
  text-align: center;
  padding: 20rpx 0;
  color: #999;
  font-size: 24rpx;
  width: 100%; /* 确保宽度100% */
}

/* 空状态 */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 100rpx 0;
  width: 100%; /* 确保宽度100% */

  .empty-icon {
    width: 200rpx;
    height: 200rpx;
    margin-bottom: 30rpx;
  }

  .empty-text {
    font-size: 28rpx;
    color: #999;
  }
}

/* 新消息提示 */
.new-message-alert {
  position: fixed;
  bottom: 220rpx;
  left: 50%;
  transform: translateX(-50%);
  background-color: #007aff;
  color: #fff;
  padding: 10rpx 20rpx;
  border-radius: 30rpx;
  box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.2);
  z-index: 99;
  animation: bounce 0.5s;
  display: flex;
  align-items: center;
  cursor: pointer;
}

.alert-content {
  display: flex;
  align-items: center;
}

.alert-icon {
  margin-right: 10rpx;
}

@keyframes bounce {
  0%,
  20%,
  50%,
  80%,
  100% {
    transform: translateX(-50%) translateY(0);
  }
  40% {
    transform: translateX(-50%) translateY(-10rpx);
  }
  60% {
    transform: translateX(-50%) translateY(-5rpx);
  }
}
</style>
